﻿using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Primitives;
using System.Reflection;

namespace MefContrib.Models.Provider.Tests
{
    using System;
    using System.Collections.Generic;
    using NUnit.Framework;


    [TestFixture]
    public class ProviderImportDefinitionTests
    {
        private MemberInfo GetDummyMemberInfo()
        {
            var memberInfo = MemberInfoServices.GetMemberInfo(typeof (DummyPart).AssemblyQualifiedName, "DummyImport");
            return memberInfo;
        }
        
        [Test, ExpectedException(typeof(ArgumentNullException))]
        public void ConstructorShouldThrowExceptionIfMemberParameterIsNull()
        {
            ProviderImportDefinition import =
                new ProviderImportDefinition(null, "contract", new List<string>(), false, false, false);
        }
        
        [Test, ExpectedException(typeof(ArgumentNullException))]
        public void ConstructorShouldThrowExceptionIfContractNameIsNull()
        {
            ProviderImportDefinition import =
                new ProviderImportDefinition(GetDummyMemberInfo(), null, new List<string>(), false, false, false);
        }
        
        
        [Test, ExpectedException(typeof(ArgumentException))]
        public void ConstructorShouldThrowExceptionIfContractNameIsEmpty()
        {
            ProviderImportDefinition import =
                new ProviderImportDefinition(GetDummyMemberInfo(), string.Empty, new List<string>(), false, false, false);
        }
        

        [Test]
        public void ConstructorShouldNotThrowExceptionIfRequiredMetadataIsNull()
        {
            ProviderImportDefinition import =
                new ProviderImportDefinition(GetDummyMemberInfo(), "contract", null, false, true, true);

            Assert.IsTrue(true);
        }

        [Test]
        public void AllowDefaultShouldReturnFalseIfPassedFalseInConstructor()
        {
            ProviderImportDefinition import =
                new ProviderImportDefinition(GetDummyMemberInfo(), "contract", new List<string>(), false, false, false);

            Assert.IsFalse(import.AllowDefault);
        }

        [Test]
        public void AllowDefaultShouldReturnTrueIfPassedTrueInConstructor()
        {
            ProviderImportDefinition import =
                new ProviderImportDefinition(GetDummyMemberInfo(), "contract", new List<string>(), true, false, false);

            Assert.IsTrue(import.AllowDefault);
        }

        [Test]
        public void IsRecomposableShouldReturnFalseIfPassedFalseInConstructor()
        {
            ProviderImportDefinition import =
                new ProviderImportDefinition(GetDummyMemberInfo(), "contract", new List<string>(), false, false, false);

            Assert.IsFalse(import.IsRecomposable);
        }

        [Test]
        public void IsRecomposableShouldReturnTrueIfPassedTrueInConstructor()
        {
            ProviderImportDefinition import =
                new ProviderImportDefinition(GetDummyMemberInfo(), "contract", new List<string>(), false, true, false);

            Assert.IsTrue(import.IsRecomposable);
        }

        [Test]
        public void IsPrerequisiteShouldReturnFalseIfPassedFalseInConstructor()
        {
            ProviderImportDefinition import =
                new ProviderImportDefinition(GetDummyMemberInfo(), "contract", new List<string>(), false, false, false);

            Assert.IsFalse(import.IsPrerequisite);
        }

        [Test]
        public void IsPrerequisiteShouldReturnTrueIfPassedTrueInConstructor()
        {
            ProviderImportDefinition import =
                new ProviderImportDefinition(GetDummyMemberInfo(), "contract", new List<string>(), false, true, true);

            Assert.IsTrue(import.IsPrerequisite);
        }

        [Test]
        public void RequiredMetadataShouldBeEmptyEnumerableIfPassedNullInConstructor()
        {
            ProviderImportDefinition import =
                new ProviderImportDefinition(GetDummyMemberInfo(), "contract", null, false, true, true);

            Assert.IsTrue(import.RequiredMetadata.GetType() == typeof(string[]));
        }

        [Test]
        public void RequiredMetadataShouldReturnValuePassedInConstructor()
        {
            List<string> metadata =
                new List<string> { "Foo", "Bar" };

            ProviderImportDefinition import =
                new ProviderImportDefinition(GetDummyMemberInfo(), "contract", metadata, false, true, true);

            Assert.AreSame(import.RequiredMetadata, metadata);
        }

        [Test]
        public void ContractNameShouldReturnValuePassedInConstructor()
        {
            ProviderImportDefinition import =
                new ProviderImportDefinition(GetDummyMemberInfo(), "contract", new List<string>(), false, true, true);

            Assert.AreEqual(import.ContractName, "contract");
        }

        [Test]
        public void MemberShouldReturnValuePassedInConstructor()
        {
            var member = GetDummyMemberInfo();

            ProviderImportDefinition import =
                new ProviderImportDefinition(member, "contract", new List<string>(), false, true, true);

            Assert.AreEqual(import.Member, member);
        }
    }
}